﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharePhone.Query
{
    public class Expression
    {
        #region Conjunction enum

        public enum Conjunction
        {
            And,
            Or,
            None
        } ;

        #endregion

        #region FieldType enum

        public enum FieldType
        {
            Text,
            Lookup,
            LookupMulti,
            Number,
            /// <summary>
            /// Date part only
            /// </summary>
            DateTime,
            /// <summary>
            /// Date and time 
            /// </summary>
            DateTimeWithTimeIncluded,
            User,
            ModStat,
            GUID
        } ;

        #endregion

        #region Operator enum

        public enum Operator
        {
            Neq,
            Lt,
            Gt,
            Eq,
            Geq,
            Leq,
            Contains,
            BeginsWith,
            IsNotNull,
            IsNull
        } ;

        #endregion
    }

    public class CamlExpression
    {
        private readonly Expression.Conjunction conj;
        private readonly Dictionary<Expression.Conjunction, List<CamlExpression>> joins;
        private readonly List<QueryPart> parts;

        public CamlExpression(Expression.Conjunction c)
        {
            parts = new List<QueryPart>();
            joins = new Dictionary<Expression.Conjunction, List<CamlExpression>>();
            conj = c;
        }

        public List<QueryPart> QueryParts
        {
            get { return parts; }
        }

        public Dictionary<Expression.Conjunction, List<CamlExpression>> Joins
        {
            get { return joins; }
        }

        public string Query
        {
            get
            {
                string query = String.Empty;
                if (Joins.Count == 0)
                    query = parts[0].ToString();
                else
                {
                    var sb = new StringBuilder();
                    foreach (Expression.Conjunction c in Joins.Keys)
                    {
                        int i = Joins[c].Count;
                        if (i == 2)
                        {
                            query = String.Format("<{0}>{1}{2}</{0}>", c, Joins[c][0].Query, Joins[c][1].Query);
                        }
                        else
                        {
                            for (int j = 0; j < i - 1; j++)
                            {
                                sb.Append(String.Format("<{0}>", c));
                            }
                            sb.Append(String.Format("{0}{1}</{2}>", Joins[c][0].Query, Joins[c][1].Query, conj));
                            for (int j = 2; j < i; j++)
                            {
                                sb.Append(String.Format("{1}</{0}>", c, Joins[c][j].Query));
                            }
                            query = sb.ToString();
                        }
                    }
                }
                return query;
            }
        }

        public void AddQueryPart(QueryPart part)
        {
            if (!parts.Contains(part))
                parts.Add(part);
        }
    }
}